package com.aaa.gs.filter;

import com.aaa.common.util.Result;
import com.aaa.common.util.ResultStatus;
import com.aaa.gs.service.RemoteCheckTokenService;
import com.alibaba.fastjson.JSON;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;

/**
 * @ FileName: SsoLoginFilter
 * @ Description:
 * @ Author:  STB
 * @ CreateTime: 2025/9/8 0008 20:53
 * @ Version: 1.0.0
 */
@Log4j2
@Component
public class SsoLoginFilter implements GlobalFilter, Ordered {
    @Value("${white_list_path}")
    private String whiteListPath;


    @Resource
    private RemoteCheckTokenService remoteCheckTokenService;


    //常量，规定前端给后端传递token时，名字必须是token不能是别的
    private static  final  String TOKEN_PARAM_NAME="token";


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("--------------------------------进入单点登录过滤器--------------------------------");
        //获取request和response对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        //获取请求路径
        String requestPath = request.getPath().toString();
        //打印
        log.info("请求路径为："+requestPath);
        //whiteListPath = /memberAuth/checkToken,/memberAuth/login,/userAuth/login,/userAuth/checkToken
        //判断白名单是否含有请求路径
        if(whiteListPath.contains(requestPath)){//包含直接放行
            //让程序继续执行
            return chain.filter(exchange);
        }
        //判断是否携带token，如果携带，获取并判断是否正确
        //定义token
        String  token = null;
        //1,先判断请求参数中是否携带token
        //   获取所有参数
        MultiValueMap<String, String> queryParams = request.getQueryParams();
        //   判断
        if(!CollectionUtils.isEmpty(queryParams)){
            //循环
            for (Map.Entry<String, List<String>> stringListEntry : queryParams.entrySet()) {
                //获取请求参数名字和参数值
                String paramName = stringListEntry.getKey();
                String paramValue = stringListEntry.getValue().get(0); //参数值，默认是list，前端可能数组
                //url?a=1&b=2&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJhZG1pbiIsInBob25lTnVtIjoiMTg1MzgwNjI5MDciLCJ1c2VyTmFtZSI6ImFkbWluIiwidXNlcklkIjoiMSIsImlhdCI6MTc1NzA1OTExOX0.13jxCpd-kYJMfGyaoaSsvAXgaJrirVRVwzOb-oRDSGk
                //判断
                if(TOKEN_PARAM_NAME.equals(paramName)){//携带
                    //给上面定义的token赋值
                    token = paramValue;
                    //如果获取到，直接跳出循环，不用管其他参数
                    break;
                }
            }
        }

        if(token==null){ //如果上面执行完，仍然是null，说明请求参数中没有携带token
            //2，再判断头部是否携带token
            //   根据名称从头部中获取token
            List<String> stringList = request.getHeaders().get(TOKEN_PARAM_NAME);
            //   判断
            if(!CollectionUtils.isEmpty(stringList)){//如果不空，说明token有值，获取第一个
                token = stringList.get(0);
            }
        }
        //再次判断  判断是否为null和是否正确
        if(token==null||!remoteCheckTokenService.checkToken(token)){//token仍然为null，说明参数和header都没有传递  或者token错误，也要返回错误
            // 不合法则返回错误信息
            Result result =new Result(ResultStatus.TOKEN_IS_NULL_ERROR.getReturnCode(),
                    ResultStatus.TOKEN_IS_NULL_ERROR.getReturnMessage(),"TOKEN问题！！！！！！！！");
            try {
                byte[] datas = JSON.toJSONString(result).getBytes("utf-8");
                DataBuffer buffer = response.bufferFactory().wrap(datas);
                //添加响应头
                response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
                //写入自定义错误信息，并返回
                return response.writeWith(Mono.just(buffer));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        log.info("--------------------------------离开了单点登录过滤器--------------------------------");
        //程序继续运行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
